home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SPACE 2
/
SPACE - Library 2 - Volume 1.iso
/
magazi~1
/
278
/
vditext.10
< prev
next >
Wrap
Text File
|
1986-11-01
|
15KB
|
307 lines
Permission to reprint or excerpt is granted only if the following
line appears at the top of the article:
ANTIC PUBLISHING INC., COPYRIGHT 1986. REPRINTED BY PERMISSION.
PROFESSIONAL GEM by Tim Oren
Column #10 - VDI Graphics: Text Output
This issue of ST PRO GEM concludes the two column series on
VDI with a look at simple VDI text output, and ways to optimize
its speed. There is also a Feedback section. You may find the
associated download file under the name GMCL10.C in DL3 of the
ATARI16 SIG (PCS-58).
To keep the size of this first discussion of text within
reason, I am going to restrict it to use of the mono-spaced system
font in its default size and orientation. Discussion of
alternate and proportionally spaced fonts, baseline rotation, and
character scaling will become a later article in this series.
DEFINITIONS. This article makes use of some terminology
which may be unfamiliar if you have not used digital typefaces.
A mono-spaced font is one in which each character occupies an
identically wide space on the screen. A proportional font has
characters which occupy different widths. For instance, an 'l'
would probably be narrower than a 'w'.
Text may be "justified" right, left, or center. This means
that the right character, left character, or center position of
the text string is constrained to a given location. In common
usage, a page of text is "ragged right" if its lines are left
justified only. The text page is "fully justified", "justified"
or (ambiguously) "right justified" if BOTH the left and right
characters are contrained to fixed columns. Full justification is
produced by inserting extra blank characters in the case of a
mono-spaced font, or by adding extra pixel columns in the case of
proportional output.
A text character (in a monospaced font) is written inside a
standard sized cell or box. Vertically, the cell extends from the
"top line" down to the "bottom line". If there are one or more
blank lines at the top or bottom, they are called "leading" and
are used to separate lines of text. The characters themselves
always fall between the "ascent line", which is the highest line
reached by characters such as 'd' and 'l', and the "descent line",
which is the lowest line in characters like 'q' and 'g'. Other
locations of interest are the "half line", which is the top of
characters like 'a' or 'n', and the "base line", which is the
bottom of characters which do not have descenders.
Before plunging into the Attribute Functions for text, you
should note that the writing mode (vswr_mode) and clipping
rectangle (vs_clip) attributes discussed in the last column (#9)
also pertain to text. Since much of the discussion of text
optimization will center on these attributes, you may want to
review them.
TEXT ATTRIBUTES. The writing color for graphics text is set
with the command:
vst_color(vdi_handle, color);
Vdi_handle is always the handle returned from graf_handle() at
application startup. Color is a word value between 0 and 15 which
designates the output color index. As discussed in previous
columns, the actual color which appears is dependent on the
current palette settings. In applications such as word and
outline processors it is important that characters and their
background provide good contrast to avoid eyestrain. In these
situations, you may want to use the setPalette and/or setColor
XBIOS functions to force the palette to a known state before
starting the application.
You can choose a variety of special output effects for your
text with the call:
vst_effects(vdi_handle, effects);
Effects is a single flag word, with the bits having the following
significance:
0 - Thicken
1 - Lighten
2 - Skew
3 - Underline
4 - Outline
5 - Shadow
In each case, turning the bit on selects the effect. Otherwise,
the effect is off. Any number of multiple effects may be
selected, but the result may not always be pleasing or legible.
The "thicken" effect widens the character strokes by one
pixel, resulting in the appearance of boldface type. The
"lighten" effect superimposes a half-tone dither on the character.
This mode is useful for indicating non-selectable text items, but
is not legible enough for other purposes.
The skew effect shifts the rows of the character to the right,
with the greatest displacement at the top. This results in the
appearance of italic text. You should be aware that the VDI does
not compensate for this effect. This means that a skewed italic
character which is immediately followed by a normal blank will be
overstruck, and part of the top of the character will disappear.
Likewise, a skewed character written to the left of an existing
normal character will overstrike part of it. There is a related
bug in the VDI clipping logic which may cause some parts of a
skewed character not to be redrawn if they fall at the edge of a
clipping rectangle, even though they should fall within the
region.
The outline effect produces output which is a one pixel
"halo" around the normal character. The shadow effect attempts to
create a "drop shadow" to the side of the character. These
effects should be used very sparingly with default sized fonts.
They often result in illegible output.
When graphics text is written, a screen coordinate must be
specified for the output. The relationship of the text to the
screen point is determined by the call:
vst_alignment(vdi_handle, hin, vin, &hout, &vout);
Hin and vin are each words, with values specifying the desired
horizontal and vertical alignment, respectively. Hout and vout
receive the actual values set by the VDI. If they differ from the
requested values, an error has occurred.
Hin may be set to zero for left justification, one for center
justification, or two for right justification. The coordinate
given when text is written becomes the "anchor point" as described
in the definitions above. The default justification is left.
Vin determines what reference line of the text is positioned
at the output coordinate. The selection values are:
0 - baseline (default)
1 - half line
2 - ascent line
3 - bottom line
4 - descent line
5 - top line
A common combination of alignments is left (0) and top line
(5). This mode guarantees that all text output will lie to the
right and below the output coordinate. This corresponds with the
AES object and GRECT coordinate systems.
Finally, the call to do the actual output is:
v_gtext(vdi_handle, x, y, string);
X and y define the screen coordinate to be used as the alignment
point. String is a pointer to a null terminated string, which
must be total eighty characters or less, exclusive of the null.
This limit is imposed by the size of the intin[] array in the VDI
binding. Be warned that it is NOT checked in the standard
binding! Exceeding it may cause memory to be overwritten.
One Inquire Function is useful with text output. The call
vqt_attributes(vdi_handle, attrib);
reads back the current attribute settings into the 10 word array
attrib[]. The main items of interest are attrib[6] through
attrib[9], which contain the width and height of characters, and
the width and height of the character cell in the current font.
You should rely on this function to obtain size information,
rather than using the output of the graf_handle() function. On
the ST, graf_handle() always returns sizes for the monochrome mode
system font, which will be incorrect in the color screen modes.
Attrib[1] will contain the current graphics text color as set
by vst_color(). Attrib[3] and [4] contain the horizontal and
vertical alignment settings, respectively. Attrib[5] contains the
current writing mode, as set by vswr_mode().
OPTIMIZATION. The most common complaint about using bit maps
for character output is lack of speed. This section suggests ways
to speed things up. By adopting all of these methods, you can
realize an improvement of two to three times in speed.
BYTE ALIGNMENT. Since writing graphic text is essentially a
bit-blit operation, characters which have "fringes", that is, do
not align evenly with byte boundaries, will suffer performance
penalities. The default system fonts in all resolutions of the ST
are a multiple of eight pixels wide, so the problem reduces to
assuring that each characters starts at a byte boundary in the
screen bit map. This will be true if the horizontal pixel address
of the left edge of the character is evenly divisible by eight.
Obviously, byte alignment is easiest to enforce when the
horizontal justification is right or left. Doing so with centered
text is possible, but requires adding padding blanks to odd length
strings.
When writing text within windows, it is helpful to assure
that the edges of the window working area are byte aligned. There
is a section of code in the download which shows a technique for
converting a user requested window position and/or size to its
working dimensions, byte-aligning the width and horizontal
position, and computing the adjusted external window coordinates.
WRITING MODE. The fastest text output mode is replace. All
other modes require reading in the target raster area and merging
it with the new information. You may find that you must use
transparent or reverse transparent mode, for instance, to use or
preserve an underlying background color other than white. In this
case, you can still do some optimization by filling in the
background color for the entire string with a v_bar() call, rather
than doing it one character cell at a time.
CLIPPING. VDI output always proceeds faster when the
clipping rectangle is turned off, and text output is no exception.
Remember that you may only do this if you are drawing into a
dialog box, or into the interior of a window which you know is on
top. (You can use the WM_TOPPED and WM_NEWTOP messages for
keeping track of the top window, or use the WF_TOP wind_get() call
to find the current top.) In both of these cases, you will know
the width of the drawing area, and you can truncate the output
string to fit exactly, rather than setting the clipping rectangle.
For this to work, you must have used the byte alignment technique
to assure that the width of the writing area is a multiple of
eight.
BINDINGS. The normal binding for v_gtext() is inefficient.
It copies the string which you supply character-by-character into
intin[] before it calls the VDI itself. In many cases, it will be
more efficient for your application to place characters directly
into intin[] and make the VDI trap call directly. To give you a
start, the code for the standard v_gtext() binding has been
included in the download. When setting up intin[], be sure not to
load more than 80 characters, or you will probably crash the
system!
MOVING TEXT. When performing text editing on the screen, you
should avoid rewriting the string under edit whenever possible.
It is always more efficient to use the raster operations to move a
string to the right or left, assuming that you have obeyed the
byte alignment rule. If you are deleting characters, blit the
unchanged part of the screen to the left, and overstrike the last
character in the string with a blank. If inserting characters,
blit the trailing portion of the string to the right before
writing in the new character.
THAT'S IT FOR NOW. This concludes the two article series on
simple VDI output. Future columns may explore more complex VDI
topics such as proportional text. If there is something you would
like to see, please use the Online Feedback to let me know!
Meanwhile, the next column will give out the locations of some of
the "hooks" and "trapdoors" built into the AES object structure,
including how to set up user-defined AES drawing objects.
>>>>>>>>>>> Demonstration of byte alignment of window interior <<<<<<<<<<<
#define FEATURES 0x0fef /* what border features are used */
WORD msg[8]; /* message from evnt_multi */
GRECT work_area; /* defines working area */
WORD w_hndl; /* handle for window being changed */
wind_calc(1, FEATURES, msg[4], msg[5], msg[6], msg[7],
&work_area.g_x, &work_area.g_y, &work_area.g_w,
&work_area.g_h);
work_area.g_x = align_x(work_area.g_x);
work_area.g_w = align_x(work_area.g_w);
wind_calc(0, FEATURES, work_area.g_x, work_area.g_y,
work_area.g_w, work_area.g_h, &msg[4], &msg[5],
&msg[6], &msg[7]);
wind_set(w_hndl, WF_CXYWH, msg[4], msg[5], msg[6], msg[7]);
>>>>>>>>>>>>>>>>>>>>> Subroutine for above <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
WORD
align_x(x) /* forces word alignment for column position */
WORD x; /* rounding to nearest word */
{
return((x & 0xfff0) + ((x & 0x0008) ? 0x0010 : 0));
}
>>>>>>>>>>>>>>>>>>>>> Standard v_gtext binding <<<<<<<<<<<<<<<<<<<<<<<<<
WORD
v_gtext( handle, x, y, string)
WORD handle, x, y;
BYTE *string;
{
WORD i;
ptsin[0] = x;
ptsin[1] = y;
i = 0;
while (intin[i++] = *string++) /* Copy characters to intin */
; /* There is NO error checking! */
contrl[0] = 8;
contrl[1] = 1;
contrl[3] = --i;
contrl[6] = handle;
vdi();
}